package physics;

import graphics.LeafNode;

import javax.media.opengl.*;

public class Triangle extends PhysicsObject {
	private static final float[] VERTICES = {0, 0, 1, 0, 0, 1};
	
	private Vector2f[] vertexCache;
	private Vector2f[] normalCache;
	
	private class Renderable extends LeafNode {
		public float scale;
		public float CoMX;
		public float CoMY;
		
		@Override public void setTranslate(float x, float y, float z) {
			super.setTranslate(x + CoMX, y + CoMY, z);
		}
		
		@Override protected void render(GL2 the_gl) {
			
			the_gl.glColor3f(1, 1, 1);
			the_gl.glBegin(GL.GL_TRIANGLES);
			for (int i = 0; i < VERTICES.length; i += 2) {
				the_gl.glVertex2f(VERTICES[i], VERTICES[i+1]);
			}
			the_gl.glEnd();
		}
	}

	
	
	public Triangle(float size) {
		centerOfMass.x = centerOfMass.y = size / 3;
		inverseMomentOfInertia = 1 / (float)(Math.pow(size, 4) / 18);
		renderable = new Renderable();
		((Renderable) renderable).scale = size;
		((Renderable) renderable).CoMX = centerOfMass.x;
		((Renderable) renderable).CoMY = centerOfMass.y;
	}
	
	public void clearCaches() {
		vertexCache = null;
		normalCache = null;
	}

	public Vector2f[] getVertices() {
		if (vertexCache == null) {
			vertexCache = new Vector2f[VERTICES.length / 2];
			Vector2f tmp = new Vector2f();
			for (int i = 0; i < VERTICES.length; i += 2) {
				tmp.x = VERTICES[i] * ((Renderable) renderable).scale;
				tmp.y = VERTICES[i+1] * ((Renderable) renderable).scale;
				tmp.sumScale(centerOfMass, -1);
				vertexCache[i/2] = new Vector2f();
				vertexCache[i/2].x = (float)(Math.cos(orientation) * tmp.x - Math.sin(orientation) * tmp.y);
				vertexCache[i/2].y = (float)(Math.sin(orientation) * tmp.x + Math.cos(orientation) * tmp.y);
				vertexCache[i/2].sum(centerOfMass);
				vertexCache[i/2].sum(position);
			}
		}
		return vertexCache;
	}
	
	public Vector2f[] getNormals() {
		if (normalCache == null) {
			Vector2f[] vertices = getVertices();
			normalCache = new Vector2f[vertices.length];

			for (int i = 0; i < vertices.length; i++) {
				normalCache[i] = new Vector2f(vertices[(i+1)%vertices.length]);
				normalCache[i].sumScale(vertices[i], -1);
				normalCache[i].normalize();
				float tmp = normalCache[i].x;
				normalCache[i].x = normalCache[i].y;
				normalCache[i].y = -tmp;
			}
		}
		return normalCache;
	}

	
	public static float getInverseMoment(float[] vertices, final float inverse_mass) {
		final Vector2f b_vect = new Vector2f(vertices[2] - vertices[0], 
				vertices[3] - vertices[1]);
		final float b = b_vect.length();
		final Vector2f diag = new Vector2f(vertices[4] - vertices[0], 
				vertices[5] - vertices[1]);
		final Vector2f b_unit = new Vector2f(b_vect);
		b_unit.normalize();
		final float a = diag.dot(b_unit);
		final Vector2f b_perp = new Vector2f(-b_unit.y, b_unit.x);
		final float h = diag.dot(b_perp);
		return inverse_mass * 12 / (h*b*b*b + h*a*b*b+h*a*a*b+b*h*h*h);
	}
}